package com.sunshine.lnuplus.view

import android.content.*
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.Button
import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.sunshine.lnuplus.R
import com.sunshine.lnuplus.adapter.ChooseWeekRecyclerAdapter
import com.sunshine.lnuplus.callback.EditLessonCallBack
import com.sunshine.lnuplus.model.LessonBean
import com.sunshine.lnuplus.model.LessonStyle
import com.sunshine.lnuplus.ui.activity.AddLessonActivity
import com.sunshine.lnuplus.utils.ColorUtils
import com.sunshine.lnuplus.utils.DateUtils
import com.sunshine.lnuplus.utils.TagHelper
import kotlinx.android.synthetic.main.layout_lesson.view.*
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList

class LessonLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    private var dayCount: Int = 5
    private var thisWeek = 1
    private var otherWeek = 1
    private var lastLessonLayoutData: LastLessonLayoutData? = null
    private lateinit var layoutMap: MutableMap<Int, LinearLayout>
    private lateinit var dateLayoutMap: MutableMap<Int, LinearLayout>
    private lateinit var lessonStyle: LessonStyle
    private lateinit var lessonList: ArrayList<LessonBean>
    private lateinit var allLessonList: ArrayList<LessonBean>   //无论是否显示非本周，这个表中都是全的
    private var fragmentManager: FragmentManager? = null
    private var isSetting = false   //设置界面不相应点击事件
    private var fragment: Fragment? = null
    private var adapter: ChooseWeekRecyclerAdapter? = null

    fun init(
        lessonList: ArrayList<LessonBean>,
        lessonStyle: LessonStyle,
        thisWeek: Int,
        otherWeek: Int,
        fragmentManager: FragmentManager?,
        isSetting: Boolean,
        fragment: Fragment?,
        adapter: ChooseWeekRecyclerAdapter?
    ) {
        val inflater = LayoutInflater.from(context)
        inflater.inflate(R.layout.layout_lesson, this)

        ColorUtils.init(context)
        this.lessonStyle = lessonStyle
        this.lessonList = lessonList
        this.allLessonList = lessonList
        this.thisWeek = thisWeek
        this.otherWeek = otherWeek
        this.fragmentManager = fragmentManager
        this.isSetting = isSetting
        this.fragment = fragment
        this.adapter = adapter
        lastLessonLayoutData = null

        //夜间模式设置背景
        if(context.getSharedPreferences("com.sunshine.lnuplus_preferences", Context.MODE_PRIVATE).getBoolean("night", false)){
            this.lessonStyle.dateAndTimeTextColor = "#FFFFFF"
            this.lessonStyle.alpha = 100.coerceAtMost(this.lessonStyle.alpha)
        }

        lessonList.forEach {
            if(it.end > lessonStyle.count){
                lessonStyle.count = it.end
            }
        }

        if(lessonStyle.sundayFirst && lessonStyle.showWeekend){
            initLessonLayoutSun()
            //如果是周日那么切换到下一周
            if(DateUtils.getTodayOfWeek() == 7){
                this.thisWeek += 1
            }
        }else{
            initLessonLayout()
        }

        initDateLayout()
        initDate()
        initTime()

        //不显示非本周兼容模式
        if(!lessonStyle.showNotInThisWeek){
            val tempLessonList = ArrayList<LessonBean>()
            lessonList.forEach {
                if(it.dayOfWeek == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) this.thisWeek -= 1
                if(it.weeks.contains(this.thisWeek)){
                    tempLessonList.add(it)
                }
                if(it.dayOfWeek == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) this.thisWeek += 1
            }
            this.lessonList = tempLessonList
        }

        layoutMap.forEach {
            for(time in 1..lessonStyle.count){
                addButton(it.key, time)
            }
        }

    }

    private fun initLessonLayout() {
        layoutMap = mutableMapOf(
            1 to Mon_layout,
            2 to Tues_layout,
            3 to Wed_layout,
            4 to Thur_layout,
            5 to Fri_layout
        )
        if(lessonStyle.showWeekend){
            val params = LayoutParams(0, LayoutParams.MATCH_PARENT, 3.0f)
            Sat_layout.layoutParams = params
            Sun_layout.layoutParams = params
            layoutMap[6] = Sat_layout
            layoutMap[7] = Sun_layout
            dayCount = 7
        }else {
            val params = LayoutParams(0, LayoutParams.MATCH_PARENT, 0.0f)
            Sat_layout.layoutParams = params
            Sun_layout.layoutParams = params
            layoutMap[6] = Sat_layout
            layoutMap[7] = Sun_layout
            dayCount = 5
        }
        layoutMap.forEach{ it.value.removeAllViews() }
    }

    private fun initLessonLayoutSun(){
        val params = LayoutParams(0, LayoutParams.MATCH_PARENT, 3.0f)
        Sat_layout.layoutParams = params
        Sun_layout.layoutParams = params
        layoutMap = mutableMapOf(
            1 to Tues_layout,
            2 to Wed_layout,
            3 to Thur_layout,
            4 to Fri_layout,
            5 to Sat_layout,
            6 to Sun_layout,
            7 to Mon_layout
        )
        dayCount = 7
        layoutMap.forEach{it.value.removeAllViews()}
    }

    private fun initDateLayout() {
        dateLayoutMap = mutableMapOf(
            0 to date_time_layout,
            1 to date_Mon_layout,
            2 to date_Tues_layout,
            3 to date_Wed_layout,
            4 to date_Thur_layout,
            5 to date_Fri_layout
        )
        if(lessonStyle.showWeekend){
            val params = LayoutParams(0, LayoutParams.MATCH_PARENT, 3.0f)
            date_Sat_layout.layoutParams = params
            date_Sun_layout.layoutParams = params
            dateLayoutMap[6] = date_Sat_layout
            dateLayoutMap[7] = date_Sun_layout
            dayCount = 7
        }else {
            val params = LayoutParams(0, LayoutParams.MATCH_PARENT, 0.0f)
            date_Sat_layout.layoutParams = params
            date_Sun_layout.layoutParams = params
            dateLayoutMap[6] = date_Sat_layout
            dateLayoutMap[7] = date_Sun_layout
            dayCount = 5
        }
        dateLayoutMap.forEach{ it.value.removeAllViews() }
    }

//    private fun initDateLayoutSun(){
//        val params = LayoutParams(0, LayoutParams.MATCH_PARENT, 3.0f)
//        date_Sat_layout.layoutParams = params
//        date_Sun_layout.layoutParams = params
//        dateLayoutMap = mutableMapOf(
//            0 to date_time_layout,
//            1 to date_Tues_layout,
//            2 to date_Wed_layout,
//            3 to date_Thur_layout,
//            4 to date_Fri_layout,
//            5 to date_Sat_layout,
//            6 to date_Sun_layout,
//            7 to date_Mon_layout
//        )
//        dayCount = 7
//        dateLayoutMap.forEach{ it.value.removeAllViews()}
//    }

    private fun addButton(dayOfWeek: Int, time: Int){
        //如果课程开始时间包括在上次添加的按钮中，那么扩展按钮
        if(lastLessonLayoutData != null && dayOfWeek == lastLessonLayoutData!!.dayOfWeek && lastLessonLayoutData!!.lessonTime.contains(time)){
            lessonList.forEach {
                if(it.dayOfWeek == dayOfWeek && it.start == time){
                    if(it.dayOfWeek == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) thisWeek -= 1
                    for(lessonTime in it.start..it.end){
                        if(!lastLessonLayoutData!!.lessonTime.contains(lessonTime)) lastLessonLayoutData!!.lessonTime.add(lessonTime)
                    }
                    when {
                        it.weeks.contains(thisWeek) -> {
                            lastLessonLayoutData!!.buttonText += "\n\n${it.start}-${it.end}\n"
                            lastLessonLayoutData!!.buttonText +=
                            it.lessonName +
                                    (if(it.location.isNotEmpty()) "\n@${it.location}" else "") +
                                    (if(lessonStyle.showTeacher && it.teacher.isNotEmpty()) "\n${it.teacher}" else "") +
                                    "\n\n"

                            //设置颜色
                            val backgroundDrawable = GradientDrawable().apply {
                                cornerRadius = lessonStyle.round.toFloat()
                                alpha = lessonStyle.alpha
                                setColor(Color.GRAY)
                            }
                            if(it.color == "0"){
                                backgroundDrawable.setColor(ColorUtils.setBackgroundColor(it.lessonName))
                            }else{
                                try {
                                    backgroundDrawable.setColor(Color.parseColor(it.color))
                                }catch (e: Exception){
                                    backgroundDrawable.setColor(Color.BLACK)
                                }
                            }
                            lastLessonLayoutData!!.lessonButton.background = backgroundDrawable
                        }
                        lessonStyle.showNotInThisWeek -> {
                            lastLessonLayoutData!!.buttonText += "\n\n${it.start}-${it.end}\n"
                            lastLessonLayoutData!!.buttonText +=
                            "[非本周]\n${it.lessonName}\n\n"
                        }
                    }
                    lastLessonLayoutData!!.lessonBeanList.add(it)
                    if(it.dayOfWeek == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) thisWeek += 1  //加回去
                }
            }
            lastLessonLayoutData!!.lessonButton.text = lastLessonLayoutData!!.buttonText
            lastLessonLayoutData!!.lessonButton.height = lessonStyle.height * lastLessonLayoutData!!.lessonTime.size + lessonStyle.heightDistant * (lastLessonLayoutData!!.lessonTime.size - 1)
        } else {
            val lessonBeanList = ArrayList<LessonBean>()
            val lessonTimeList = ArrayList<Int>()
            var inThisWeekCount = 0

            lessonList.forEach {
                if(it.dayOfWeek == dayOfWeek && it.start == time){
                    if(it.dayOfWeek == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) thisWeek -= 1
                    lessonBeanList.add(it)
                    for(lessonTime in it.start..it.end){
                        if(!lessonTimeList.contains(lessonTime)) lessonTimeList.add(lessonTime)
                    }
                    if(it.weeks.contains(thisWeek)) inThisWeekCount++
                    if(it.dayOfWeek == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) thisWeek += 1
                }
            }
            when {
                lessonBeanList.size == 0 -> {
                    layoutMap[dayOfWeek]?.addView(addButtonEmpty(dayOfWeek, time))
                }
                inThisWeekCount == 0 -> {
                    if(lessonStyle.showNotInThisWeek) {
                        layoutMap[dayOfWeek]?.addView(
                            addButtonLesson(
                                lessonBeanList,
                                lessonTimeList,
                                dayOfWeek,
                                false
                            )
                        )
                    } else {
                        layoutMap[dayOfWeek]?.addView(addButtonEmpty(dayOfWeek, time))
                    }
                }
                else -> {
                    layoutMap[dayOfWeek]?.addView(addButtonLesson(lessonBeanList, lessonTimeList, dayOfWeek, true))
                }
            }
        }
    }

    private fun addButtonLesson(lessonBeanList: ArrayList<LessonBean>, lessonTimeList: ArrayList<Int>, dayOfWeek: Int, inThisWeek: Boolean): Button {
        val button = Button(context)
        var buttonText = ""
        val backgroundDrawable = GradientDrawable().apply {
            cornerRadius = lessonStyle.round.toFloat()
            alpha = lessonStyle.alpha
            setColor(Color.GRAY)
        }
        val params = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
        params.topMargin = lessonStyle.heightDistant
        params.leftMargin = lessonStyle.widthDistant
        params.rightMargin = lessonStyle.widthDistant
        if(dayOfWeek == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) thisWeek -= 1
        lessonBeanList.forEach {
                when {
                    it.weeks.contains(thisWeek) -> {
                        buttonText += it.lessonName +
                                (if(it.location.isNotEmpty()) "\n@${it.location}" else "") +
                                (if(lessonStyle.showTeacher && it.teacher.isNotEmpty()) "\n${it.teacher}" else "") +
                                "\n\n"

                        //设置颜色
                        if(it.color == "0"){
                            backgroundDrawable.setColor(ColorUtils.setBackgroundColor(it.lessonName))
                        }else{
                            try {
                                backgroundDrawable.setColor(Color.parseColor(it.color))
                            }catch (e: Exception){
                                backgroundDrawable.setColor(Color.BLACK)
                            }
                        }
                    }

                    lessonStyle.showNotInThisWeek -> {
                        buttonText += "[非本周]\n${it.lessonName}\n\n"
                    }
                }
        }
        if(dayOfWeek == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) {
            thisWeek += 1
        }
        buttonText = buttonText.substring(0, buttonText.length - 2)
        button.text = buttonText
        if(lessonStyle.textLeft) button.gravity = Gravity.START
        else button.gravity = Gravity.CENTER
        try {
            button.setTextColor(Color.parseColor(lessonStyle.textColor))
        }catch (e: Exception) {
            button.setTextColor(Color.WHITE)
        }
        button.textSize = lessonStyle.textSize.toFloat()
        button.setPadding(lessonStyle.padding, lessonStyle.padding, lessonStyle.padding, lessonStyle.padding)
        button.height = lessonStyle.height * lessonTimeList.size + lessonStyle.heightDistant * (lessonTimeList.size - 1)
        button.background = backgroundDrawable
        button.layoutParams = params
        button.isAllCaps = false
        if(!isSetting){
            button.setOnClickListener {
                val tempLessonList = ArrayList<LessonBean>()
                if(lessonStyle.detailShowNotInThisWeek){
                    allLessonList.forEach {
                        if(it.dayOfWeek == dayOfWeek && it.start == lessonTimeList[0]){
                            tempLessonList.add(it)
                        }
                    }
                }
                LessonDetailDialog.newInstance(if(lessonStyle.detailShowNotInThisWeek) tempLessonList else lessonBeanList, object : EditLessonCallBack{
                    override fun updateView() {
                        adapter?.notifyDataSetChanged()
                    }

                }).show(fragmentManager!!, "")
            }
            button.setOnLongClickListener {
                val bundle = Bundle()
                bundle.putInt("day_of_week", dayOfWeek)
                bundle.putInt("time",lessonBeanList[0].start)
                //注意不能putExtras会空指针
                fragment?.startActivityForResult(Intent(context, AddLessonActivity::class.java).putExtra("time", bundle), TagHelper.TIMETABLE)
                true
            }
        }

        lastLessonLayoutData = LastLessonLayoutData(button, button.text.toString(), dayOfWeek, lessonTimeList, lessonBeanList)
        return button
    }

    private fun addButtonEmpty(dayOfWeek: Int, time: Int): Button {
        val button = Button(context)
        val params = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
        params.topMargin = lessonStyle.heightDistant
        button.height = lessonStyle.height
        button.setBackgroundColor(0)
        button.layoutParams = params
        if(!isSetting){
            button.setOnLongClickListener {
                val bundle = Bundle()
                bundle.putInt("day_of_week", dayOfWeek)
                bundle.putInt("time", time)
                fragment?.startActivityForResult(Intent(context, AddLessonActivity::class.java).putExtra("time", bundle), TagHelper.TIMETABLE)
                true
            }
        }

        return button
    }

    private fun initTime(){
        rootView.time_layout.removeAllViews()
        val params = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
        params.topMargin = lessonStyle.heightDistant
        for(lessonTime in 1..lessonStyle.count){
            val button = Button(context)
            var buttonText = "$lessonTime"
            if(lessonStyle.showTime){
                try {
                    buttonText += "\n${lessonStyle.lessonTime[lessonTime - 1]}"
                } catch (e: Exception){ }
            }
            button.text = buttonText
            button.height = lessonStyle.height
            button.textSize = lessonStyle.timeTextSize.toFloat()
            button.setPadding(0, 0, 0, 0)
            try {
                button.setTextColor(Color.parseColor(lessonStyle.dateAndTimeTextColor))
            }catch (e: Exception) {
                button.setTextColor(Color.WHITE)
            }

            button.setBackgroundColor(0)
            button.layoutParams = params
            rootView.time_layout.addView(button)
        }
    }

    private fun initDate(){
        val dateFormat = SimpleDateFormat("MM/dd")
        val beginDate = Date()
        val calendar = Calendar.getInstance()
        var weekDeference = thisWeek - otherWeek
        val month = Button(context)
        month.textSize = lessonStyle.timeTextSize.toFloat()
        try {
            month.setTextColor(Color.parseColor(lessonStyle.dateAndTimeTextColor))
        }catch (e: Exception) {
            month.setTextColor(Color.WHITE)
        }
        month.setBackgroundColor(0)
        month.setPadding(0,0,0,0)
        for(day in 1 .. dayCount){
            val button = Button(context)
            calendar.time = beginDate
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + (day - DateUtils.getTodayOfWeek() + 7 * weekDeference))
            val endDate = dateFormat.parse(dateFormat.format(calendar.time))
            button.text = "周${DateUtils.getTodayOfWeekString(day)}\n${dateFormat.format(endDate)}"
            button.textSize = lessonStyle.timeTextSize.toFloat()
            try {
                button.setTextColor(Color.parseColor(lessonStyle.dateAndTimeTextColor))
            }catch (e: Exception) {
                button.setTextColor(Color.WHITE)
            }
            button.setBackgroundColor(0)
            button.setPadding(0,0,0,0)
            if(DateUtils.getTodayOfWeek() == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) weekDeference -= 1
            if(weekDeference == 0 && day == DateUtils.getTodayOfWeek()){
                val backgroundDrawable = GradientDrawable()
                backgroundDrawable.cornerRadius = lessonStyle.round.toFloat()
                try {
                    backgroundDrawable.setColor(Color.parseColor(lessonStyle.dateColor))
                } catch (e: Exception) {
                    backgroundDrawable.setColor(Color.RED)
                }
                button.background = backgroundDrawable
                button.setTextColor(Color.WHITE)
            }
            if(DateUtils.getTodayOfWeek() == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) weekDeference += 1
            //周日模式向下推一格
            if(lessonStyle.sundayFirst && lessonStyle.showWeekend){
                if(day < 7) {
                    dateLayoutMap[day + 1]?.addView(button)
                }else{
                    calendar.time = beginDate
                    calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + (day - DateUtils.getTodayOfWeek() + 7 * (weekDeference - 1)))
                    val endDate = dateFormat.parse(dateFormat.format(calendar.time))
                    button.text = "周${DateUtils.getTodayOfWeekString(day)}\n${dateFormat.format(endDate)}"
                    dateLayoutMap[1]?.addView(button)
                }
            }else{
                dateLayoutMap[day]?.addView(button)
            }
            month.text = "${dateFormat.format(endDate).split("/")[0].toInt()}月"
        }
        dateLayoutMap[0]?.addView(month)
        //if(DateUtils.getTodayOfWeek() == 7 && lessonStyle.sundayFirst && lessonStyle.showWeekend) thisWeek += 1
    }
}

data class LastLessonLayoutData(
    var lessonButton: Button,
    var buttonText: String,
    var dayOfWeek: Int,
    var lessonTime: ArrayList<Int>,
    val lessonBeanList: ArrayList<LessonBean>
)